package com.gexiaobao.pigeon.ui.fragment.mine.banking

import android.graphics.BitmapFactory
import android.os.Bundle
import androidx.core.view.isVisible
import com.blankj.utilcode.util.ThreadUtils.runOnUiThread
import com.gexiaobao.pigeon.app.base.BaseFragment
import com.gexiaobao.pigeon.app.eventViewModel
import com.gexiaobao.pigeon.app.ext.Constant
import com.gexiaobao.pigeon.app.ext.showMessage
import com.gexiaobao.pigeon.app.model.param.IdCardParams
import com.gexiaobao.pigeon.app.rxui.tablayout.listener.GlideEngine
import com.gexiaobao.pigeon.app.util.Base64Util
import com.gexiaobao.pigeon.app.util.DatetimeUtil
import com.gexiaobao.pigeon.app.util.FileUtil
import com.gexiaobao.pigeon.app.util.MeSandboxFileEngine
import com.gexiaobao.pigeon.app.util.PictureUtil
import com.gexiaobao.pigeon.app.util.RxToast
import com.gexiaobao.pigeon.databinding.FragmentOcrRecognitionBinding
import com.gexiaobao.pigeon.viewmodel.MineBankingViewModel
import com.luck.picture.lib.basic.PictureSelectionModel
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.config.SelectModeConfig
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.language.LanguageConfig
import com.luck.picture.lib.style.PictureSelectorStyle
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.util.setOnclickNoRepeat
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.File
import java.io.IOException
import java.net.URLEncoder


/**
 * @Author      : hxw
 * @Date        : 2024/3/14 9:44
 * @Describe    : 上传身份证
 */
class FragmentOcrRecognition : BaseFragment<MineBankingViewModel, FragmentOcrRecognitionBinding>() {

    private var mIdCardType: String = ""
    private var idCardFrontFile: File? = null
    private var idCardBackFile: File? = null
    private val HTTP_CLIENT = OkHttpClient().newBuilder().build()
    private var idCardNumberTypeFront = 0
    private var idCardNumberTypeBack = 0

    override fun initView(savedInstanceState: Bundle?) {
        mDatabind.includeBar.tvWhiteTitle.text = "上传证件"
    }

    override fun onBindViewClick() {
        super.onBindViewClick()
        setOnclickNoRepeat(mDatabind.includeBar.ivBack, mDatabind.ivIdCardFront, mDatabind.ivIdCardBack, mDatabind.btnSubmitOcrInfo) {
            when (it) {
                mDatabind.ivIdCardBack -> {
                    selectHeadIcon("back")
                    mIdCardType = "back"
                }

                mDatabind.ivIdCardFront -> {
                    selectHeadIcon("front")
                    mIdCardType = "front"
                }

                mDatabind.includeBar.ivBack -> {
                    nav().navigateUp()
                }

                mDatabind.btnSubmitOcrInfo -> {
                    when {
                        idCardFrontFile == null -> showMessage("请上传身份证正面照")
                        idCardBackFile == null -> showMessage("请上传身份证背面照")
                        idCardNumberTypeFront == -1 || idCardNumberTypeBack == -1 -> showMessage("请上传有效身份证件")
                        else -> {
                            val param = IdCardParams(
                                idCardFront = idCardFrontFile,
                                idCardBack = idCardBackFile,
                                name = mDatabind.etOcrName.text.toString(),
                                code = mDatabind.etOcrIdNum.text.toString()
                            )
                            showLoading("提交中...")
                            mViewModel.uploadIdCard(param)
                        }
                    }
                }
            }
        }
    }

    override fun createObserver() {
        super.createObserver()
        mViewModel.uploadIdCardResult.observe(viewLifecycleOwner) {
            dismissLoading()
            if (it.isSuccess) {
                eventViewModel.toRefreshData.value = true
                nav().navigateUp()
            } else {
                RxToast.showToast(it.errorMsg)
            }
        }
    }

    private fun selectHeadIcon(type: String) {
        val selectionModel: PictureSelectionModel = PictureSelector.create(context)
            .openGallery(SelectMimeType.ofImage())
            .setSelectorUIStyle(PictureSelectorStyle())
            .setImageEngine(GlideEngine.createGlideEngine())
            .setCompressEngine(PictureUtil.getCompressFileEngine())
            .setSandboxFileEngine(MeSandboxFileEngine())
            .setSelectionMode(SelectModeConfig.SINGLE)
            .setCameraInterceptListener(PictureUtil.getCustomCameraEvent())
            .setPermissionDescriptionListener(PictureUtil.getPermissionDescriptionListener())
            .setPreviewInterceptListener(PictureUtil.getPreviewInterceptListener())
            .setPermissionDeniedListener(PictureUtil.getPermissionDeniedListener())
            .setQueryFilterListener { false }
            .isLoopAutoVideoPlay(false)
            .isPageSyncAlbumCount(true)
            .setLanguage(LanguageConfig.SYSTEM_LANGUAGE)
            .setQuerySortOrder("")
            .isDisplayCamera(true)
            .isOpenClickSound(false)
            .isPreviewImage(true)
            .isMaxSelectEnabledMask(true)
            .isDirectReturnSingle(true)
        selectionModel.forResult(object : OnResultCallbackListener<LocalMedia> {
            override fun onResult(result: ArrayList<LocalMedia>?) {
                val path = result!![0].realPath
                val file = File(path)
                val bitmap = BitmapFactory.decodeFile(path)
                if (type == "front") {
                    idCardFrontFile = file
                    idCard(path, "front")
                    mDatabind.ivIdCardFront.setImageBitmap(bitmap)
                } else {
                    idCardBackFile = file
                    idCard(path, "back")
                    mDatabind.ivIdCardBack.setImageBitmap(bitmap)
                }
            }

            override fun onCancel() {}
        })
    }

    private fun idCard(path: String?, type: String) {
        runOnUiThread {
            showLoading("识别中...")
        }
        Thread {
            val mediaType: MediaType = "application/x-www-form-urlencoded".toMediaTypeOrNull()!!
            // image 可以通过 getFileContentAsBase64("C:\fakepath\微信图片_20230809113403.jpg") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
            val body = ("id_card_side=$mIdCardType&image=" + URLEncoder.encode(
                Base64Util.encode(FileUtil.readFileByBytes(path)), "UTF-8"
            ) + "&url=https%3A%2F%2Faip.baidubce.com%2Frest%2F2.0%2Focr%2Fv1%2Fidcard&detect_risk=false&detect_quality=false&detect_photo=false&detect_card=false&detect_direction=false"
                    ).toRequestBody(mediaType)
            val request = Request.Builder()
                .url("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + getAccessToken())//Constant.ACCESS_TOKEN
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build()
            val response = HTTP_CLIENT.newCall(request).execute()
            runOnUiThread {
                dismissLoading()
            }
            setCardInfo(response.body?.string(), type)
        }.start()
    }

    @Throws(IOException::class)
    private fun getAccessToken(): String? {
        val mediaType = "application/x-www-form-urlencoded".toMediaTypeOrNull()
        val body = RequestBody.create(
            mediaType, "grant_type=client_credentials&client_id=" + Constant.API_KEY
                    + "&client_secret=" + Constant.SECRET_KEY
        )
        val request: Request = Request.Builder()
            .url("https://aip.baidubce.com/oauth/2.0/token")
            .method("POST", body)
            .addHeader("Content-Type", "application/x-www-form-urlencoded")
            .build()
        val response = HTTP_CLIENT.newCall(request).execute()
        return JSONObject(response.body!!.string()).getString("access_token")
    }

    private fun setCardInfo(data: String?, type: String) {
        try {
            runOnUiThread {
                if (JSONObject(data.toString()).has("error_code")) {
                    if (JSONObject(data.toString()).getInt("error_code") == 111) {
                        RxToast.showToast("令牌过期")
                        return@runOnUiThread
                    }
                }
                if (type == "back") {
                    if (JSONObject(data.toString()).has("idcard_number_type")) {
                        idCardNumberTypeBack = JSONObject(data.toString()).getInt("idcard_number_type")
                        if (idCardNumberTypeBack == -1) {
                            RxToast.showToast("识别失败，请重新上传")
                            return@runOnUiThread
                        }
                    }
                    idCardNumberTypeBack = 1
                    val currentDate = DatetimeUtil.getTimeStringYear()
                    val wordResultBack = JSONObject(data.toString()).getJSONObject("words_result")
                    if (wordResultBack.has("失效日期")) {
                        val date = wordResultBack.getJSONObject("失效日期")
                        val wordsDate = date.getString("words")
                        if (currentDate.isNotEmpty() && wordsDate.isNotEmpty()) {
                            if (wordsDate != "长期") {
                                if (currentDate.toInt() > wordsDate.toInt()) {
                                    RxToast.showToast("证件已过期，请上传有效证件")
                                }
                            }
                        }
                    }
                } else {
                    if (JSONObject(data.toString()).has("idcard_number_type")) {
                        idCardNumberTypeFront = JSONObject(data.toString()).getInt("idcard_number_type")
                        if (idCardNumberTypeFront == -1) {
                            RxToast.showToast("识别失败，请重新上传")
                            mDatabind.etOcrName.text = ""
                            mDatabind.etOcrIdNum.text = ""
                            mDatabind.tvOcrCheckInfo.isVisible = false
                            return@runOnUiThread
                        }
                    }
                    idCardNumberTypeFront = 1
                    val name: JSONObject?
                    val idCardNum: JSONObject?
                    val wordResult = data?.let { JSONObject(it).getJSONObject("words_result") }
                    if (wordResult != null) {
                        if (wordResult.has("姓名")) {
                            name = wordResult.getJSONObject("姓名")
                            if (name != null) {
                                val wordName = name.getString("words")
                                mDatabind.etOcrName.text = wordName
                            }
                        }
                        if (wordResult.has("公民身份号码")) {
                            idCardNum = wordResult.getJSONObject("公民身份号码")
                            if (idCardNum != null) {
                                val wordIdNUm = idCardNum.getString("words")
                                mDatabind.etOcrIdNum.text = wordIdNUm
                            }
                        }
                        mDatabind.tvOcrCheckInfo.isVisible = true
                    }

                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

}